package persistence

import (
	"context"
	"encoding/json"
	"fmt"

	"Data-API-MCP/backend/internal/domain/entity"
	"Data-API-MCP/backend/internal/domain/repository"

	"gorm.io/gorm"
)

// MCPProtocolRepository MCP协议仓储实现
type MCPProtocolRepository struct {
	db *gorm.DB
}

// NewMCPProtocolRepository 创建MCP协议仓储实例
func NewMCPProtocolRepository(db *gorm.DB) *MCPProtocolRepository {
	return &MCPProtocolRepository{db: db}
}

// MessageRepository 获取消息仓储
func (r *MCPProtocolRepository) MessageRepository() repository.MCPMessageRepository {
	return &mcpMessageRepository{db: r.db}
}

// ContextRepository 获取上下文仓储
func (r *MCPProtocolRepository) ContextRepository() repository.MCPContextRepository {
	return &mcpContextRepository{db: r.db}
}

// ModelRepository 获取模型仓储
func (r *MCPProtocolRepository) ModelRepository() repository.MCPModelRepository {
	return &mcpModelRepository{db: r.db}
}

// mcpMessageRepository MCP消息仓储实现
type mcpMessageRepository struct {
	db *gorm.DB
}

// CreateMessage 创建消息
func (r *mcpMessageRepository) CreateMessage(ctx context.Context, message *entity.MCPMessage) error {
	return r.db.WithContext(ctx).Create(message).Error
}

// GetMessage 获取消息
func (r *mcpMessageRepository) GetMessage(ctx context.Context, id string) (*entity.MCPMessage, error) {
	var message entity.MCPMessage
	if err := r.db.WithContext(ctx).First(&message, "id = ?", id).Error; err != nil {
		return nil, err
	}
	return &message, nil
}

// ListMessagesByContext 获取指定上下文的消息列表
func (r *mcpMessageRepository) ListMessagesByContext(ctx context.Context, contextID string, offset, limit int) ([]*entity.MCPMessage, error) {
	var messages []*entity.MCPMessage
	err := r.db.WithContext(ctx).
		Where("context_id = ?", contextID).
		Order("sequence_num asc").
		Offset(offset).
		Limit(limit).
		Find(&messages).Error
	return messages, err
}

// UpdateMessageStatus 更新消息状态
func (r *mcpMessageRepository) UpdateMessageStatus(ctx context.Context, id string, status string) error {
	return r.db.WithContext(ctx).
		Model(&entity.MCPMessage{}).
		Where("id = ?", id).
		Update("status", status).Error
}

// DeleteMessage 删除消息
func (r *mcpMessageRepository) DeleteMessage(ctx context.Context, id string) error {
	return r.db.WithContext(ctx).Delete(&entity.MCPMessage{}, "id = ?", id).Error
}

// mcpContextRepository MCP上下文仓储实现
type mcpContextRepository struct {
	db *gorm.DB
}

// CreateContext 创建上下文
func (r *mcpContextRepository) CreateContext(ctx context.Context, mcpContext *entity.MCPContext) error {
	return r.db.WithContext(ctx).Create(mcpContext).Error
}

// GetContext 获取上下文
func (r *mcpContextRepository) GetContext(ctx context.Context, id string) (*entity.MCPContext, error) {
	var mcpContext entity.MCPContext
	if err := r.db.WithContext(ctx).First(&mcpContext, "id = ?", id).Error; err != nil {
		return nil, err
	}
	return &mcpContext, nil
}

// UpdateContext 更新上下文
func (r *mcpContextRepository) UpdateContext(ctx context.Context, mcpContext *entity.MCPContext) error {
	return r.db.WithContext(ctx).Save(mcpContext).Error
}

// UpdateContextState 更新上下文状态
func (r *mcpContextRepository) UpdateContextState(ctx context.Context, id string, state interface{}) error {
	stateJSON, err := json.Marshal(state)
	if err != nil {
		return fmt.Errorf("序列化状态失败: %w", err)
	}

	return r.db.WithContext(ctx).
		Model(&entity.MCPContext{}).
		Where("id = ?", id).
		Update("state", stateJSON).Error
}

// DeleteContext 删除上下文
func (r *mcpContextRepository) DeleteContext(ctx context.Context, id string) error {
	return r.db.WithContext(ctx).Delete(&entity.MCPContext{}, "id = ?", id).Error
}

// ListContextsByService 获取指定服务的上下文列表
func (r *mcpContextRepository) ListContextsByService(ctx context.Context, serviceID string, offset, limit int) ([]*entity.MCPContext, error) {
	var contexts []*entity.MCPContext
	err := r.db.WithContext(ctx).
		Where("service_id = ?", serviceID).
		Order("created_at desc").
		Offset(offset).
		Limit(limit).
		Find(&contexts).Error
	return contexts, err
}

// mcpModelRepository MCP模型仓储实现
type mcpModelRepository struct {
	db *gorm.DB
}

// CreateModel 创建模型
func (r *mcpModelRepository) CreateModel(ctx context.Context, model *entity.MCPModel) error {
	return r.db.WithContext(ctx).Create(model).Error
}

// GetModel 获取模型
func (r *mcpModelRepository) GetModel(ctx context.Context, id string) (*entity.MCPModel, error) {
	var model entity.MCPModel
	if err := r.db.WithContext(ctx).First(&model, "id = ?", id).Error; err != nil {
		return nil, err
	}
	return &model, nil
}

// UpdateModel 更新模型
func (r *mcpModelRepository) UpdateModel(ctx context.Context, model *entity.MCPModel) error {
	return r.db.WithContext(ctx).Save(model).Error
}

// DeleteModel 删除模型
func (r *mcpModelRepository) DeleteModel(ctx context.Context, id string) error {
	return r.db.WithContext(ctx).Delete(&entity.MCPModel{}, "id = ?", id).Error
}

// ListModels 获取模型列表
func (r *mcpModelRepository) ListModels(ctx context.Context, offset, limit int) ([]*entity.MCPModel, error) {
	var models []*entity.MCPModel
	err := r.db.WithContext(ctx).
		Order("created_at desc").
		Offset(offset).
		Limit(limit).
		Find(&models).Error
	return models, err
}

// GetModelByVersion 根据版本获取模型
func (r *mcpModelRepository) GetModelByVersion(ctx context.Context, name, version string) (*entity.MCPModel, error) {
	var model entity.MCPModel
	err := r.db.WithContext(ctx).
		Where("name = ? AND version = ?", name, version).
		First(&model).Error
	if err != nil {
		return nil, err
	}
	return &model, nil
}
